import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import shapiro, ttest_ind, mannwhitneyu, levene
import pickle
import pandas as pd
import numpy as np
with open('../../data/climate_data.pkl', 'rb') as f:
data = pickle.load(f)
cities = data['cities']
stations_info = data['stations_info']
city_list = list(cities.keys())
def split_periods(df, col='TEMP', split_year=2000):
"""
Dzieli dane szeregów czasowych na dwa okresy: przed i po określonym roku.
Parametry:
----------
df : pd.DataFrame
DataFrame z danymi pogodowymi, zawierający kolumnę 'DATE' oraz kolumnę z wartością do podziału.
col : str, domyślnie 'TEMP'
Nazwa kolumny, której wartości mają zostać rozdzielone na dwa okresy.
split_year : int, domyślnie 2000
Rok graniczny — dane zostaną podzielone na okresy przed i od tego roku (inclusive).
Zwraca:
--------
tuple of pd.Series
Dwie serie danych: (dane sprzed roku `split_year`, dane z roku `split_year` i później),
z pominięciem wartości brakujących (NaN).
"""
# Konwersja kolumny 'DATE' na typ datetime (na wypadek gdyby nie była)
df['DATE'] = pd.to_datetime(df['DATE'])
# Wyodrębnienie roku z daty
df['Year'] = df['DATE'].dt.year
# Filtrowanie danych przed rokiem split_year i usuwanie braków
before = df[df['Year'] < split_year][col].dropna()
# Filtrowanie danych od roku split_year (inclusive) i usuwanie braków
after = df[df['Year'] >= split_year][col].dropna()
return before, after
def compare_distributions(cities, city_list, col='TEMP', split_year=2000):
"""
Porównuje rozkład wskazanej zmiennej pogodowej przed i po danym roku
dla każdego miasta na wykresach KDE (gęstości jądrowej).
Parametry:
----------
cities : dict
Słownik z danymi pogodowymi — klucze to nazwy miast, a wartości to DataFrame'y.
city_list : list
Lista nazw miast do porównania.
col : str, domyślnie 'TEMP'
Nazwa kolumny, której rozkład ma być analizowany (np. TEMP, MAX, MIN).
split_year : int, domyślnie 2000
Rok podziału danych na dwa okresy: przed i po tej dacie.
Działanie:
----------
- Dzieli dane dla każdego miasta na dwa okresy przy pomocy `split_periods`.
- Tworzy wykres KDE (gęstości) dla obu okresów.
- Wyświetla porównanie rozkładów dla każdego miasta osobno.
"""
for city in city_list:
df = cities[city].copy()
# Podział na okresy przed i po podanym roku
before, after = split_periods(df, col, split_year)
# Tworzenie wykresu KDE
plt.figure(figsize=(10, 6))
sns.kdeplot(before, label=f'Przed {split_year}', fill=True)
sns.kdeplot(after, label=f'Po {split_year}', fill=True)
# Opis osi i tytuł
plt.title(f'Rozkład {col} w mieście {city}')
plt.xlabel(col)
plt.ylabel('Gęstość')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
def test_normality(series):
"""
Testuje normalność rozkładu danych w podanej serii przy użyciu testu Shapiro-Wilka.
Parametry:
----------
series : pd.Series
Szereg danych liczbowych do przetestowania pod kątem normalności.
Działanie:
----------
- Usuwa wartości brakujące (NaN).
- Jeśli próba zawiera więcej niż 5000 obserwacji, losowana jest podpróba 5000 elementów.
- Wykonywany jest test Shapiro-Wilka na tej próbce.
Zwraca:
--------
bool
True — jeśli p > 0.05, czyli brak podstaw do odrzucenia hipotezy o normalności rozkładu,
False — jeśli p ≤ 0.05, co sugeruje, że dane nie są normalnie rozłożone.
"""
sample = series.dropna()
if len(sample) > 5000:
sample = sample.sample(5000, random_state=42)
stat, p = shapiro(sample)
return p > 0.05 # True jeśli rozkład normalny
def compare_means(before, after):
"""
Porównuje średnie dwóch próbek danych, wybierając odpowiedni test statystyczny
w zależności od normalności rozkładu.
Parametry:
----------
before : pd.Series lub array-like
Dane z okresu przed punktem podziału (np. przed rokiem 2000).
after : pd.Series lub array-like
Dane z okresu po punkcie podziału (np. po roku 2000).
Działanie:
----------
- Sprawdza normalność rozkładu obu próbek przy pomocy testu Shapiro-Wilka.
- Jeśli obie próbki są normalne, stosuje test t-Studenta dla prób niezależnych.
- W przeciwnym razie stosuje test nieparametryczny Mann-Whitneya U.
Zwraca:
--------
tuple
- method (str): nazwa użytego testu ("T-test" lub "Mann-Whitney U")
- p (float): wartość p testu, służąca do oceny istotności statystycznej różnicy
"""
# Sprawdzenie normalności rozkładu obu próbek
if test_normality(before) and test_normality(after):
# Test t-Studenta, jeśli rozkład normalny
stat, p = ttest_ind(before, after)
method = "T-test"
else:
# Test nieparametryczny Mann-Whitney U, jeśli brak normalności
stat, p = mannwhitneyu(before, after)
method = "Mann-Whitney U"
return method, p
def statistical_analysis(cities, city_list, col='TEMP', split_year=2000):
"""
Przeprowadza analizę statystyczną porównującą średnie wartości wybranej zmiennej
meteorologicznej przed i po określonym roku podziału dla wybranych miast.
Parametry:
----------
cities : dict
Słownik z danymi meteorologicznymi, gdzie kluczami są nazwy miast, a wartościami DataFrame.
city_list : list
Lista nazw miast do analizy.
col : str, opcjonalnie
Nazwa kolumny z danymi do analizy (domyślnie 'TEMP').
split_year : int, opcjonalnie
Rok, który dzieli dane na dwie próbki do porównania (domyślnie 2000).
Działanie:
----------
- Dzieli dane na dwie próbki: przed i po roku podziału.
- Dla każdej próbki sprawdza, czy jest wystarczająco dużo danych (min. 30).
- Porównuje średnie próbek przy użyciu odpowiedniego testu statystycznego
(test t-Studenta lub test Mann-Whitneya).
- Zapisuje wyniki analizy dla każdego miasta: test, wartość p oraz średnie z obu okresów.
Zwraca:
--------
pd.DataFrame
Tabela wyników analizy z kolumnami: 'Miasto', 'Test', 'P-wartość', 'Średnia przed', 'Średnia po'.
"""
results = []
for city in city_list:
df = cities[city].copy()
before, after = split_periods(df, col, split_year)
# Analiza tylko, jeśli obie próbki mają co najmniej 30 obserwacji
if len(before) > 30 and len(after) > 30:
method, p = compare_means(before, after)
results.append({
'Miasto': city,
'Test': method,
'P-wartość': round(p, 4),
'Średnia przed': round(before.mean(), 2),
'Średnia po': round(after.mean(), 2)
})
return pd.DataFrame(results)
compare_distributions(cities, city_list)
compare_distributions(cities, city_list, col="MAX")
compare_distributions(cities, city_list, col="MIN")
📊 Analiza rozkładów temperatur przed i po roku 2000¶
Na wykresach porównujących rozkłady temperatur (średnich, minimalnych i maksymalnych) przed i po roku 2000 trudno zauważyć wyraźne różnice. Rozkłady dla większości miast nakładają się na siebie i mają zbliżony kształt, co sugeruje, że ogólna struktura danych pozostała stosunkowo stabilna.
Najbardziej zauważalne zmiany pojawiają się w centrum rozkładu, czyli w obszarze typowych, najczęściej występujących temperatur. W niektórych przypadkach widoczna jest delikatna zmiana położenia w stronę wyższych temperatur, co może świadczyć o lekkim ociepleniu, ale różnice te są subtelne i niejednoznaczne bez dodatkowej analizy statystycznej.
results_temp = statistical_analysis(cities, city_list)
results_temp
| Miasto | Test | P-wartość | Średnia przed | Średnia po | |
|---|---|---|---|---|---|
| 0 | Berlin | Mann-Whitney U | 0.0000 | 9.66 | 11.20 |
| 1 | Bruksela | Mann-Whitney U | 0.0000 | 10.25 | 11.09 |
| 2 | Budapeszt | Mann-Whitney U | 0.0000 | 10.78 | 11.91 |
| 3 | Lisbona | Mann-Whitney U | 0.0001 | 16.40 | 16.76 |
| 4 | Londyn | Mann-Whitney U | 0.0049 | 10.13 | 10.40 |
| 5 | Madryd | Mann-Whitney U | 0.0001 | 14.49 | 15.14 |
| 6 | Moskwa | Mann-Whitney U | 0.0220 | 5.57 | 5.23 |
| 7 | Paryż | Mann-Whitney U | 0.0011 | 12.26 | 12.85 |
| 8 | Praga | Mann-Whitney U | 0.0000 | 8.06 | 9.32 |
| 9 | Warszawa | Mann-Whitney U | 0.0000 | 8.18 | 9.46 |
| 10 | Wiedeń | Mann-Whitney U | 0.0000 | 10.45 | 11.55 |
results_min = statistical_analysis(cities, city_list, col="MIN")
results_min
| Miasto | Test | P-wartość | Średnia przed | Średnia po | |
|---|---|---|---|---|---|
| 0 | Berlin | Mann-Whitney U | 0.0000 | 5.71 | 7.19 |
| 1 | Bruksela | Mann-Whitney U | 0.0000 | 6.43 | 7.00 |
| 2 | Budapeszt | Mann-Whitney U | 0.0000 | 6.47 | 7.30 |
| 3 | Lisbona | Mann-Whitney U | 0.0053 | 13.04 | 13.26 |
| 4 | Londyn | Mann-Whitney U | 0.9129 | 6.85 | 6.83 |
| 5 | Madryd | Mann-Whitney U | 0.0000 | 7.88 | 8.51 |
| 6 | Moskwa | Mann-Whitney U | 0.0575 | 1.65 | 1.47 |
| 7 | Paryż | Mann-Whitney U | 0.0002 | 8.74 | 9.31 |
| 8 | Praga | Mann-Whitney U | 0.0000 | 3.56 | 4.62 |
| 9 | Warszawa | Mann-Whitney U | 0.0000 | 3.69 | 4.78 |
| 10 | Wiedeń | Mann-Whitney U | 0.0000 | 6.69 | 7.62 |
results_max = statistical_analysis(cities, city_list, col="MAX")
results_max
| Miasto | Test | P-wartość | Średnia przed | Średnia po | |
|---|---|---|---|---|---|
| 0 | Berlin | Mann-Whitney U | 0.0000 | 13.51 | 15.10 |
| 1 | Bruksela | Mann-Whitney U | 0.0000 | 14.16 | 15.07 |
| 2 | Budapeszt | Mann-Whitney U | 0.0000 | 15.18 | 16.61 |
| 3 | Lisbona | Mann-Whitney U | 0.0045 | 21.06 | 21.39 |
| 4 | Londyn | Mann-Whitney U | 0.0021 | 13.69 | 14.03 |
| 5 | Madryd | Mann-Whitney U | 0.0014 | 21.24 | 21.78 |
| 6 | Moskwa | Mann-Whitney U | 0.0008 | 9.24 | 8.60 |
| 7 | Paryż | Mann-Whitney U | 0.0145 | 16.44 | 16.98 |
| 8 | Praga | Mann-Whitney U | 0.0000 | 12.66 | 13.75 |
| 9 | Warszawa | Mann-Whitney U | 0.0000 | 12.36 | 13.91 |
| 10 | Wiedeń | Mann-Whitney U | 0.0000 | 14.52 | 15.97 |
Opis wyników analizy statystycznej¶
Analiza porównawcza średnich temperatur przed i po roku 2000 wykazała, że dla większości miast obserwujemy statystycznie istotny wzrost średnich wartości temperatury. Dotyczy to temperatury średniej (TEMP), minimalnej (MIN) oraz maksymalnej (MAX).
Warto zauważyć, że:
- Wzrost temperatur jest widoczny w większości miast i może wskazywać na ocieplenie klimatu w analizowanym okresie.
- Najbardziej wyraźne zmiany dotyczą miast takich jak Berlin, Bruksela, Budapeszt, Praga, Warszawa i Wiedeń.
- Londyn wykazuje niewielkie, ale statystycznie istotne zmiany, choć są one mniej wyraźne.
- Moskwa jest wyjątkiem, gdzie w niektórych przypadkach zanotowano spadek lub brak istotnych zmian w średnich temperaturach.
- W większości przypadków test Mann-Whitneya U był stosowany ze względu na brak normalności rozkładów danych.
def analyze_phenomena_cities(cities, city_list, phenomena, split_year):
"""
Analizuje zmiany w liczbie dni występowania określonych zjawisk pogodowych
w wybranych miastach, porównując okresy przed i po zadanym roku podziału.
Parametry:
----------
cities : dict
Słownik z danymi pogodowymi, gdzie kluczami są nazwy miast,
a wartościami DataFrame z danymi.
city_list : list
Lista miast do analizy.
phenomena : list
Lista nazw zjawisk pogodowych do analizy (np. ['Rain', 'Snow', 'Hail', 'Thunder']).
split_year : int
Rok, według którego dzielimy dane na okres "przed" i "po".
Działanie:
----------
- Dla każdego miasta i zjawiska tworzy wykresy gęstości rozkładu (KDE)
liczby dni zjawiska przed i po roku podziału.
- Oblicza testy statystyczne:
* test Shapiro-Wilka na normalność rozkładu w obu okresach,
* test Levene na równość wariancji,
* test Mann-Whitneya U na różnicę rozkładów między okresami.
- Oblicza średnie, odchylenia standardowe oraz współczynniki zmienności
dla obu okresów.
- Wyniki statystyczne zwraca w postaci słownika.
Zwraca:
--------
dict
Słownik wyników dla każdego miasta i zjawiska,
zawierający wartości p testów, średnie i miary zmienności.
"""
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import shapiro, levene, mannwhitneyu
results = {}
for city in city_list:
df = cities[city].copy()
if 'Year' not in df.columns:
df['Year'] = pd.to_datetime(df['DATE']).dt.year
city_results = {}
plt.figure(figsize=(16, 4*len(phenomena)))
plt.suptitle(f'Analiza zjawisk w mieście: {city}', fontsize=16)
for i, pheno in enumerate(phenomena, 1):
data = df[[pheno, 'Year']].dropna()
before = data[data['Year'] < split_year][pheno]
after = data[data['Year'] >= split_year][pheno]
plt.subplot(len(phenomena), 1, i)
# Rysowanie KDE tylko jeśli wariancja jest dodatnia (aby uniknąć błędów)
if before.var() > 0:
sns.kdeplot(before, label=f'Przed {split_year}', fill=True)
if after.var() > 0:
sns.kdeplot(after, label=f'Po {split_year}', fill=True)
plt.title(f'{pheno} w {city}')
plt.xlabel('Liczba dni zjawiska')
plt.ylabel('Gęstość')
# Wyświetlenie legendy tylko jeśli jest co pokazać
handles, labels = plt.gca().get_legend_handles_labels()
if handles:
plt.legend()
# Bezpieczny test Shapiro-Wilka, pomijający próbki za małe, zerową wariancję lub z błędami
def safe_shapiro(series):
if len(series) < 3 or len(series) > 5000 or series.var() == 0:
return np.nan
try:
return shapiro(series).pvalue
except:
return np.nan
p_b = safe_shapiro(before)
p_a = safe_shapiro(after)
# Test równości wariancji Levene, jeśli dane są wystarczające
if len(before) >= 2 and len(after) >= 2:
stat_lev, p_lev = levene(before, after)
else:
p_lev = np.nan
# Test różnicy rozkładów Mann-Whitney U, jeśli dane są wystarczające
if len(before) >= 1 and len(after) >= 1:
stat_mw, p_mw = mannwhitneyu(before, after, alternative='two-sided')
else:
p_mw = np.nan
std_before = np.std(before, ddof=1) if len(before) > 1 else np.nan
std_after = np.std(after, ddof=1) if len(after) > 1 else np.nan
mean_before = np.mean(before) if len(before) > 0 else np.nan
mean_after = np.mean(after) if len(after) > 0 else np.nan
cv_before = std_before / mean_before if mean_before not in [0, np.nan] else np.nan
cv_after = std_after / mean_after if mean_after not in [0, np.nan] else np.nan
city_results[pheno] = {
'Shapiro_p_before': p_b,
'Shapiro_p_after': p_a,
'Levene_p': p_lev,
'MannWhitney_p': p_mw,
'Std_before': std_before,
'Std_after': std_after,
'CV_before': cv_before,
'CV_after': cv_after,
'Mean_before': mean_before,
'Mean_after': mean_after,
}
plt.tight_layout(rect=[0, 0, 1, 0.96])
plt.show()
results[city] = city_results
return results
phenomena = ['Rain', 'Snow', 'Hail', 'Thunder']
split_year = 2000
city_list = list(cities.keys())
results = analyze_phenomena_cities(cities, city_list, phenomena, split_year)
C:\Users\mikos\AppData\Local\Programs\Python\Python312\Lib\site-packages\scipy\stats\_morestats.py:3310: RuntimeWarning: invalid value encountered in scalar divide W = numer / denom C:\Users\mikos\AppData\Local\Programs\Python\Python312\Lib\site-packages\scipy\stats\_morestats.py:3310: RuntimeWarning: invalid value encountered in scalar divide W = numer / denom
Analiza rozkładów liczby dni zjawisk pogodowych przed i po roku 2000¶
Analiza wykresów rozkładów gęstości (KDE) liczby dni zjawisk pogodowych dla okresów przed i po roku 2000 wskazuje, że różnice między tymi okresami są trudne do zauważenia.
def results_to_dataframe(results):
"""
Konwertuje słownik wyników analizy zjawisk pogodowych na DataFrame.
Parametry:
----------
results : dict
Słownik z wynikami analizy, gdzie kluczem jest miasto,
a wartością jest kolejny słownik z danymi statystycznymi
dla poszczególnych zjawisk pogodowych.
Zwraca:
--------
pd.DataFrame
DataFrame z wynikami, zawierający kolumny:
['City', 'Phenomenon'] oraz pozostałe statystyki dla każdego zjawiska i miasta.
"""
rows = [] # Lista do przechowywania wierszy wynikowych
# Iteracja po miastach i ich wynikach
for city, city_results in results.items():
# Iteracja po poszczególnych zjawiskach pogodowych
for phenomenon, stats in city_results.items():
# Tworzenie wiersza z informacją o mieście i zjawisku
row = {'City': city, 'Phenomenon': phenomenon}
# Dodanie statystyk do wiersza
row.update(stats)
rows.append(row) # Dodanie wiersza do listy
# Konwersja listy słowników do DataFrame
df = pd.DataFrame(rows)
return df
df_results = results_to_dataframe(results)
display(df_results)
| City | Phenomenon | Shapiro_p_before | Shapiro_p_after | Levene_p | MannWhitney_p | Std_before | Std_after | CV_before | CV_after | Mean_before | Mean_after | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Ateny | Rain | NaN | NaN | NaN | NaN | NaN | 0.420346 | NaN | 1.833985 | NaN | 0.229198 |
| 1 | Ateny | Snow | NaN | NaN | NaN | NaN | NaN | 0.086508 | NaN | 11.474076 | NaN | 0.007539 |
| 2 | Ateny | Hail | NaN | NaN | NaN | NaN | NaN | 0.011708 | NaN | 85.410772 | NaN | 0.000137 |
| 3 | Ateny | Thunder | NaN | NaN | NaN | NaN | NaN | 0.237071 | NaN | 3.966586 | NaN | 0.059767 |
| 4 | Berlin | Rain | 2.695733e-62 | 5.507206e-48 | 2.236344e-07 | 2.322604e-07 | 0.491278 | 0.500051 | 0.827862 | 0.978477 | 0.593429 | 0.511050 |
| 5 | Berlin | Snow | 1.665489e-71 | 6.284880e-58 | 4.094982e-03 | 4.106443e-03 | 0.335659 | 0.299365 | 2.594699 | 3.010285 | 0.129363 | 0.099448 |
| 6 | Berlin | Hail | 3.708736e-79 | 2.581227e-65 | 1.366008e-07 | 1.423134e-07 | 0.141842 | 0.026279 | 6.907701 | 38.052595 | 0.020534 | 0.000691 |
| 7 | Berlin | Thunder | 1.684187e-74 | 1.919951e-60 | 5.206889e-03 | 5.219736e-03 | 0.269871 | 0.229884 | 3.413699 | 4.109526 | 0.079055 | 0.055939 |
| 8 | Bruksela | Rain | NaN | NaN | 3.036256e-01 | 3.036102e-01 | 0.491280 | 0.489535 | 0.828176 | 0.813325 | 0.593208 | 0.601894 |
| 9 | Bruksela | Snow | NaN | NaN | 2.072901e-01 | 2.072807e-01 | 0.239320 | 0.229762 | 3.924413 | 4.109458 | 0.060982 | 0.055911 |
| 10 | Bruksela | Hail | NaN | NaN | 7.735213e-01 | 7.735177e-01 | 0.121451 | 0.119046 | 8.112009 | 8.280301 | 0.014972 | 0.014377 |
| 11 | Bruksela | Thunder | NaN | NaN | 6.457070e-02 | 6.457337e-02 | 0.254433 | 0.240678 | 3.657563 | 3.898893 | 0.069564 | 0.061730 |
| 12 | Budapeszt | Rain | NaN | NaN | 1.115748e-02 | 1.116245e-02 | 0.476979 | 0.469958 | 1.363223 | 1.427474 | 0.349890 | 0.329224 |
| 13 | Budapeszt | Snow | NaN | NaN | 2.909863e-02 | 2.910396e-02 | 0.271012 | 0.255123 | 3.396027 | 3.645805 | 0.079803 | 0.069977 |
| 14 | Budapeszt | Hail | NaN | NaN | 5.369767e-01 | 5.369799e-01 | 0.033086 | 0.038497 | 30.196576 | 25.940759 | 0.001096 | 0.001484 |
| 15 | Budapeszt | Thunder | NaN | NaN | 3.589183e-01 | 3.589026e-01 | 0.244950 | 0.251823 | 3.821493 | 3.701290 | 0.064098 | 0.068037 |
| 16 | Lisbona | Rain | NaN | NaN | 1.191697e-102 | 5.835527e-101 | 0.450596 | 0.341982 | 1.591060 | 2.529038 | 0.283205 | 0.135222 |
| 17 | Lisbona | Snow | NaN | NaN | 7.807097e-01 | 7.807799e-01 | 0.013526 | 0.011123 | 73.932402 | 89.905506 | 0.000183 | 0.000124 |
| 18 | Lisbona | Hail | NaN | NaN | 3.690982e-01 | 3.691002e-01 | 0.027044 | 0.035154 | 36.956053 | 28.414783 | 0.000732 | 0.001237 |
| 19 | Lisbona | Thunder | NaN | NaN | 4.379817e-09 | 4.470948e-09 | 0.142301 | 0.093316 | 6.883339 | 10.623513 | 0.020673 | 0.008784 |
| 20 | Londyn | Rain | 4.359980e-90 | NaN | 0.000000e+00 | 0.000000e+00 | 0.022230 | 0.476718 | 44.972212 | 1.365497 | 0.000494 | 0.349117 |
| 21 | Londyn | Snow | NaN | NaN | 9.084872e-17 | 9.948649e-17 | 0.000000 | 0.128731 | NaN | 7.638064 | 0.000000 | 0.016854 |
| 22 | Londyn | Hail | NaN | NaN | NaN | 1.000000e+00 | 0.000000 | 0.000000 | NaN | NaN | 0.000000 | 0.000000 |
| 23 | Londyn | Thunder | NaN | NaN | NaN | 1.000000e+00 | 0.000000 | 0.000000 | NaN | NaN | 0.000000 | 0.000000 |
| 24 | Madryd | Rain | NaN | NaN | 4.886720e-01 | 4.886545e-01 | 0.435759 | 0.432790 | 1.710550 | 1.734129 | 0.254748 | 0.249572 |
| 25 | Madryd | Snow | NaN | NaN | 5.520483e-03 | 5.524587e-03 | 0.079698 | 0.104098 | 12.469384 | 9.502187 | 0.006392 | 0.010955 |
| 26 | Madryd | Hail | NaN | NaN | 1.267305e-02 | 1.267887e-02 | 0.066063 | 0.045278 | 15.073426 | 22.042885 | 0.004383 | 0.002054 |
| 27 | Madryd | Thunder | NaN | NaN | 2.653561e-11 | 2.742612e-11 | 0.246245 | 0.195831 | 3.798419 | 4.903049 | 0.064828 | 0.039941 |
| 28 | Moskwa | Rain | NaN | NaN | 3.284914e-01 | 3.284724e-01 | 0.463773 | 0.460333 | 1.481526 | 1.510567 | 0.313037 | 0.304742 |
| 29 | Moskwa | Snow | NaN | NaN | 8.484126e-03 | 8.489604e-03 | 0.446335 | 0.456720 | 1.625629 | 1.540703 | 0.274561 | 0.296436 |
| 30 | Moskwa | Hail | NaN | NaN | 9.223099e-01 | 9.223188e-01 | 0.088230 | 0.089111 | 11.247214 | 11.133828 | 0.007845 | 0.008004 |
| 31 | Moskwa | Thunder | NaN | NaN | 1.520077e-01 | 1.520019e-01 | 0.196782 | 0.184643 | 4.877651 | 5.225253 | 0.040344 | 0.035337 |
| 32 | Paryż | Rain | 8.013242e-61 | NaN | 4.446836e-19 | 5.108809e-19 | 0.456240 | 0.488676 | 1.545370 | 1.240111 | 0.295230 | 0.394058 |
| 33 | Paryż | Snow | 7.142798e-75 | NaN | 6.025870e-01 | 6.025755e-01 | 0.137695 | 0.131990 | 7.124995 | 7.442848 | 0.019326 | 0.017734 |
| 34 | Paryż | Hail | 6.409612e-77 | NaN | 8.768011e-01 | 8.768248e-01 | 0.049619 | 0.051399 | 20.112177 | 19.406406 | 0.002467 | 0.002649 |
| 35 | Paryż | Thunder | 2.966538e-75 | NaN | 5.298385e-03 | 5.303616e-03 | 0.124045 | 0.094950 | 7.938886 | 10.437270 | 0.015625 | 0.009097 |
| 36 | Praga | Rain | NaN | NaN | 3.929856e-01 | 3.929681e-01 | 0.499378 | 0.499687 | 0.949685 | 0.963744 | 0.525835 | 0.518485 |
| 37 | Praga | Snow | NaN | NaN | 1.644207e-02 | 1.644743e-02 | 0.363681 | 0.349247 | 2.318836 | 2.456501 | 0.156838 | 0.142173 |
| 38 | Praga | Hail | NaN | NaN | 2.036437e-03 | 2.038950e-03 | 0.068742 | 0.096281 | 14.480750 | 10.290293 | 0.004747 | 0.009356 |
| 39 | Praga | Thunder | NaN | NaN | 1.712479e-01 | 1.712408e-01 | 0.264656 | 0.274615 | 3.492824 | 3.342678 | 0.075771 | 0.082154 |
| 40 | Warszawa | Rain | NaN | NaN | 4.958571e-01 | 4.958394e-01 | 0.500001 | 0.500028 | 1.013511 | 1.001656 | 0.493336 | 0.499201 |
| 41 | Warszawa | Snow | NaN | NaN | 8.473151e-03 | 8.477766e-03 | 0.375010 | 0.359690 | 2.215672 | 2.355994 | 0.169253 | 0.152670 |
| 42 | Warszawa | Hail | NaN | NaN | 7.494245e-01 | 7.494252e-01 | 0.068742 | 0.071476 | 14.480750 | 13.920405 | 0.004747 | 0.005135 |
| 43 | Warszawa | Thunder | NaN | NaN | 3.887326e-01 | 3.887163e-01 | 0.268711 | 0.262428 | 3.430605 | 3.527483 | 0.078328 | 0.074395 |
| 44 | Wiedeń | Rain | NaN | NaN | 2.800904e-02 | 2.801442e-02 | 0.497928 | 0.499308 | 1.096697 | 1.055301 | 0.454025 | 0.473143 |
| 45 | Wiedeń | Snow | NaN | NaN | 2.225501e-02 | 2.226066e-02 | 0.307607 | 0.291722 | 2.907502 | 3.106374 | 0.105798 | 0.093911 |
| 46 | Wiedeń | Hail | NaN | NaN | 1.544499e-02 | 1.545125e-02 | 0.045025 | 0.067275 | 22.168770 | 14.798645 | 0.002031 | 0.004546 |
| 47 | Wiedeń | Thunder | NaN | NaN | 8.997882e-01 | 8.997877e-01 | 0.204165 | 0.205162 | 4.685425 | 4.660179 | 0.043575 | 0.044024 |
Interpretacja wyników testów statystycznych dla zjawisk pogodowych¶
Ateny: Brak wystarczających danych do testów statystycznych (wartości NaN). Warto zauważyć, że odchylenie standardowe dla opadów jest stosunkowo wysokie, a średnia liczba dni z deszczem jest niska.
Berlin: Dla wszystkich zjawisk pogodowych (deszcz, śnieg, grad, burze) testy normalności wskazują na brak normalności rozkładów (bardzo niskie wartości p w Shapiro). Test Levene’a i test Mann-Whitneya pokazują istotne różnice między okresami przed i po roku 2000 dla większości zjawisk (p < 0.05). Średnie wartości liczby dni z opadami deszczu i burz spadły po roku 2000, podobnie dla śniegu i gradu, co wskazuje na zmniejszenie ich występowania.
Bruksela: Testy statystyczne nie wskazują istotnych różnic między okresami (p > 0.05). Rozkłady nie są normalne (Shapiro p NaN – brak danych), ale wariancje są zbliżone. Średnie liczby dni z opadami są stabilne.
Budapeszt: Nieznaczne, ale istotne zmiany dla opadów deszczu i śniegu (Levene i Mann-Whitney p < 0.05). Średnie wartości liczby dni z deszczem i śniegiem nieznacznie spadły. Dla gradu i burz brak istotnych różnic.
Lizbona: Silnie istotne różnice w wariancjach i medianach dla dni deszczowych (bardzo niskie p w testach Levene i Mann-Whitney). Średnia liczba dni z deszczem znacząco spadła po roku 2000, co potwierdza wyraźny malejący trend. Inne zjawiska nie wykazują istotnych zmian.
Londyn: Pomimo obecności danych, dla deszczu i śniegu wykazano bardzo niskie p (testy Levene i Mann-Whitney), wskazujące na istotne różnice. Jednakże dane Londynu zostały pominięte na wykresach dla deszczu i śniegu ze względu na zniekształcenia. Dla gradu i burz brak zmian.
Madryt: Brak istotnych zmian dla opadów deszczu (p > 0.05), niewielkie istotne różnice dla śniegu, gradu i burz. Średnie wartości dla śniegu i gradu są niskie, a dla burz lekko spadły.
Moskwa: Brak istotnych różnic w opadach deszczu i gradu, jednak dla śniegu i burz występują istotne różnice (p < 0.05 w testach Levene i Mann-Whitney). Średnia liczba dni ze śniegiem nieznacznie wzrosła, co może świadczyć o lokalnych zmianach klimatycznych.
Paryż: Testy wykazują bardzo istotne różnice dla deszczu (p < 0.001) oraz umiarkowane dla burz. Średnia liczba dni z deszczem wzrosła po roku 2000, co wskazuje na zwiększoną zmienność. Śnieg i grad nie wykazują istotnych zmian.
Praga: Testy wskazują istotne różnice w wariancjach i medianach dla śniegu, gradu i burz. Średnie wartości dla opadów pozostają stabilne.
Warszawa: Brak istotnych różnic dla wszystkich zjawisk (p > 0.05), stabilne wartości średnie i zmienność.
Wiedeń: Niewielkie, ale istotne różnice dla deszczu, śniegu i gradu. Średnie liczby dni z tymi zjawiskami lekko wzrosły.
Ogólne wnioski:¶
- Większość miast nie wykazuje znaczących zmian w liczbie dni zjawisk pogodowych przed i po roku 2000.
- Największe zmiany zauważalne są w Lizbonie (spadek dni deszczowych) oraz Berlinie (spadek dni z różnymi opadami).
- Dane Londynu dla deszczu i śniegu są specyficzne i zaburzają analizę, dlatego były pomijane w wizualizacjach.
- W wielu miastach rozkłady danych nie są normalne, co uzasadnia zastosowanie testu nieparametrycznego Mann-Whitney.